package org.create.builder;

import org.create.bean.FieldInfo;
import org.create.bean.TableInfo;
import org.create.utils.DataTool;
import org.create.utils.DateTool;
import org.create.utils.IoTool;
import org.create.utils.LogTool;

import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static org.create.bean.Constants.*;
import static org.create.bean.Constants.JAVA_SUFFIX;

public class BuildServiceImpl {
    private static BufferedWriter bw;

    private static void buildPackageComment(TableInfo tableInfo) throws IOException {
        String beanName = tableInfo.getBeanName();
        writer("package " + PACKAGE_BASE + "." + PACKAGE_SERVICE + ".impl;", 2);
        writer("import " + PACKAGE_BASE + "." + PACKAGE_PO + "." + beanName + ";");
        writer("import " + PACKAGE_BASE + "." + PACKAGE_QUERY + ".SimplePage;");
        writer("import " + PACKAGE_BASE + "." + PACKAGE_QUERY + "." + beanName + "Query;");
        writer("import " + PACKAGE_BASE + "." + PACKAGE_ENUMS + ".PageSize;");
        writer("import " + PACKAGE_BASE + "." + PACKAGE_MAPPERS + "." + beanName + "Mapper;");
        writer("import " + PACKAGE_BASE + "." + PACKAGE_SERVICE + "." + beanName + "Service;");
        writer("import " + PACKAGE_BASE + "." + PACKAGE_VO + ".PaginationResultVo;");
        writer("import org.springframework.stereotype.Service;", 2);
        writer("import javax.annotation.Resource;");
        writer("import java.util.List;", 3);
    }

    private static void buildDescriptionComment(TableInfo tableInfo) throws IOException {
        writer("/**");
        writer(" * Description " + tableInfo.getComment() + "实现类");
        writer(" * date " + DateTool.DateFormat(new Date(), YMD_HMS));
        writer(" */");
    }

    private static void buildClassComment(TableInfo tableInfo) throws IOException {
        String beanName = tableInfo.getBeanName();
        writer("@Service(value = \"" + beanName + "Service\")");
        writer("public class " + beanName + "ServiceImpl implements " + beanName + "Service {");
        writer("    @Resource");
        writer("    private " + beanName + "Mapper<" + beanName + ", " + beanName + "Query> " + DataTool.firstChatToLower(beanName) + "Mapper;", 2);
        buildFieldDescriptionComment("根据条件查询列表");
        writer("    @Override");
        writer("    public List<" + beanName + "> findListByParam(" + beanName + "Query query) {");
        writer("        return " + DataTool.firstChatToLower(beanName) + "Mapper.selectList(query);");
        writer("    }", 2);
        buildFieldDescriptionComment("根据条件查询数量");
        writer("    @Override");
        writer("    public Integer findCountByParam(" + beanName + "Query query) {");
        writer("        return " + DataTool.firstChatToLower(beanName) + "Mapper.selectCount(query);");
        writer("    }", 2);
        buildFieldDescriptionComment("分页查询方法");
        writer("    @Override");
        writer("    public PaginationResultVo<" + beanName + "> findListByPage(" + beanName + "Query query) {");
        writer("        int count = findCountByParam(query);");
        writer("        int pageSize = query.getPageSize() == null ? PageSize.SIZE15.getSize() : query.getPageSize();");
        writer("        SimplePage page = new SimplePage(query.getPageNo(), count, pageSize);");
        writer("        query.setSimplePage(page);");
        writer("        List<" + beanName + "> list = findListByParam(query);");
        writer("        return new PaginationResultVo<>(count, page.getPageSize(), page.getPageNo(), page.getCountTotal(), list);");
        writer("    }", 2);

        buildFieldDescriptionComment("新增");
        writer("    @Override");
        writer("    public Integer add(" + beanName + " bean) {");
        writer("        return " + DataTool.firstChatToLower(beanName) + "Mapper.insert(bean);");
        writer("    }", 2);

        buildFieldDescriptionComment("新增或修改");
        writer("    @Override");
        writer("    public Integer addOrUpdate(" + beanName + " bean) {");
        writer("        return " + DataTool.firstChatToLower(beanName) + "Mapper.insertOrUpdate(bean);");
        writer("    }", 2);

        buildFieldDescriptionComment("批量新增");
        writer("    @Override");
        writer("    public Integer addBatch(List<" + beanName + "> listBean) {");
        writer("        if (listBean == null || listBean.isEmpty()) {");
        writer("            return 0;");
        writer("        }");
        writer("        return " + DataTool.firstChatToLower(beanName) + "Mapper.insertBatch(listBean);");
        writer("    }", 2);

        buildFieldDescriptionComment("批量新增或更新");
        writer("    @Override");
        writer("    public Integer addOrUpdateBatch(List<" + beanName + "> listBean) {");
        writer("        if (listBean == null || listBean.isEmpty()) {");
        writer("            return 0;");
        writer("        }");
        writer("        return " + DataTool.firstChatToLower(beanName) + "Mapper.insertOrUpdateBatch(listBean);");
        writer("    }", 2);
        for (Map.Entry<String, List<FieldInfo>> entry : tableInfo.getKeyIndexMap().entrySet()) {
            List<FieldInfo> fieldInfoList = entry.getValue();
            StringBuilder sb = new StringBuilder();
            StringBuilder params = new StringBuilder();
            StringBuilder args = new StringBuilder();
            int loop = 1;
            for (FieldInfo fieldInfo : fieldInfoList) {
                sb.append(DataTool.firstChatToUpper(fieldInfo.getPropertyName()));
                params.append(fieldInfo.getJavaType()).append(" ").append(fieldInfo.getPropertyName());
                args.append(fieldInfo.getPropertyName());
                if (loop < fieldInfoList.size()) {
                    loop++;
                    sb.append("And");
                    params.append(", ");
                    args.append(", ");
                }
            }
            buildFieldDescriptionComment("根据" + sb + "查询");
            writer("    @Override");
            writer("    public " + beanName + " get" + beanName + "By" + sb + "(" + params + ") {");
            writer("        return " + DataTool.firstChatToLower(beanName) + "Mapper.selectBy" + sb + "(" + args + ");");
            writer("    }", 2);
            buildFieldDescriptionComment("根据" + sb + "修改");
            writer("    @Override");
            writer("    public Integer update" + beanName + "By" + sb + "(" + beanName + " bean, " + params + ") {");
            writer("        return " + DataTool.firstChatToLower(beanName) + "Mapper.updateBy" + sb + "(bean, " + args + ");");
            writer("    }", 2);
            buildFieldDescriptionComment("根据" + sb + "删除");
            writer("    @Override");
            writer("    public Integer delete" + beanName + "By" + sb + "(" + params + ") {");
            writer("        return " + DataTool.firstChatToLower(beanName) + "Mapper.deleteBy" + sb + "(" + args + ");");
            writer("    }");
        }
        writer("}");
    }

    private static void buildFieldDescriptionComment(String description) throws IOException {
        writer("    /**");
        writer("     * " + description);
        writer("     */");
    }

    private static void writer(String str) throws IOException {
        writer(str, 1);
    }

    private static void writer(String str, int num) throws IOException {
        bw.write(str);
        if (num > 0) {
            appendLine(num);
        }
    }

    private static void appendLine(int loop) throws IOException {
        if (loop == 1) {
            bw.newLine();
        } else {
            for (int i = 0; i < loop; i++) {
                bw.newLine();
            }
        }
    }

    public static void run(List<TableInfo> tableInfoList) {
        for (TableInfo tableInfo : tableInfoList) {
            File file = new File(PATH_SERVICE + "impl/" + tableInfo.getBeanName() + "ServiceImpl" + JAVA_SUFFIX);
            File dir = file.getParentFile();
            boolean d = dir.mkdirs();
            LogTool.printLog(d, "新建目录", dir);
            try {
                boolean r = file.createNewFile();
                LogTool.printLog(r, "新建文件", file);
                bw = IoTool.createBw(file);
                buildPackageComment(tableInfo);
                buildDescriptionComment(tableInfo);
                buildClassComment(tableInfo);
            } catch (Exception e) {
                LogTool.printError(e);
            } finally {
                IoTool.close();
            }
        }
    }
}
